using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices;
using System.Security.Principal;


namespace ChangeOSPassword
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnDo_Click(object sender, EventArgs e)
        {
            int symAMT = Convert.ToInt32(txtSymbolAMT.Text);
            int charAMT = Convert.ToInt32(txtCharAMT.Text);
            int numAMT = Convert.ToInt32(txtNumberAMT.Text);
            int times = 0;
            string newPassword = "";
            StringBuilder sbTmp = new StringBuilder();
            int ac = 0;
            int charStart = 97,charEnd=122;
            int symbolStart = 33, symbolEnd = 47;
            int numberStart = 48, numberEnd = 57;
            if (txtTimes.Text != "")
            {
                times = Convert.ToInt32(txtTimes.Text);
            }
            txtResult.Text = "";

            string successMsg = "The password was not changed.";
            if (times > 0)
            {
                Random rnd = null;
                string oldPass = txtCurPwd.Text;
                for (int i = 0; i < times; i++)
                {
                    newPassword = "";

                    sbTmp.Remove(0, sbTmp.Length);
                    rnd = new Random(DateTime.Now.Millisecond + i);
                    for (int j = 0; j < numAMT; j++)
                    {
                        ac = rnd.Next(numberStart, numberEnd);
                        sbTmp.Append(Chr(ac));
                    }
                    newPassword += sbTmp.ToString();

                    sbTmp.Remove(0, sbTmp.Length);
                    rnd = new Random(DateTime.Now.Minute + i);
                    for (int j = 0; j < symAMT; j++)
                    {
                        ac = rnd.Next(symbolStart, symbolEnd);
                        sbTmp.Append(Chr(ac));
                    }
                    newPassword += sbTmp.ToString();

                    sbTmp.Remove(0, sbTmp.Length);
                    rnd = new Random(DateTime.Now.Second + i);
                    for (int j = 0; j < charAMT; j++)
                    {
                        ac = rnd.Next(charStart, charEnd);
                        sbTmp.Append(Chr(ac));
                    }
                    newPassword += sbTmp.ToString();

                    txtResult.Text += newPassword + "\r\n";
                    if (chkChangePwd.Checked && (chkResetCurrent.Checked || txtNewPwd.Text!=""))
                    {
                        try
                        {
                            chanagePassword(oldPass, newPassword);
                        }
                        catch
                        {
                            if (i == 0)
                            {
                                MessageBox.Show("Error! Old password is wrong!");
                            }
                            else
                            {
                                MessageBox.Show("Error!The last successful changed password is:" + oldPass);
                            }
                            return;
                        }
                    }
                    oldPass = newPassword;
                }
                if (chkChangePwd.Checked && (chkResetCurrent.Checked || txtNewPwd.Text != ""))
                {
                    successMsg = "Successful! Current password is:" + newPassword;
                    if (chkResetCurrent.Checked)
                    {
                        try
                        {
                            chanagePassword(oldPass, txtCurPwd.Text);
                            successMsg = "Successful! Current password is:" + txtCurPwd.Text;
                        }
                        catch
                        {
                            MessageBox.Show("Error!The last successful changed password is:" + oldPass);
                            return;
                        }                        
                    }
                    else
                    {
                        if (txtNewPwd.Text != "")
                        {
                            try
                            {
                                chanagePassword(oldPass, txtNewPwd.Text);
                                successMsg = "Successful! Current password is:" + txtNewPwd.Text;
                            }
                            catch
                            {
                                MessageBox.Show("Error!The last successful changed password is:" + oldPass);
                                return;
                            }
                        }
                        else
                        {
                            successMsg = "Successful! Current password is:" + oldPass;
                        }
                    }
                }
                txtResult.Text += successMsg + Environment.NewLine;
                System.Windows.Forms.MessageBox.Show(successMsg);
            }
        }

        public void chanagePassword(string oldPass, string newPwd)
        {

            string strLDAP = "LDAP://" + txtDomainName.Text;
            string DomainName = txtDomainName.Text;
            string UserName = txtCurUserName.Text;
            try
            {
                using (DirectoryEntry objDE = new DirectoryEntry(strLDAP, DomainName + "\\" + UserName, oldPass))
                {
                    DirectorySearcher deSearcher = new DirectorySearcher(objDE);
                    deSearcher.Filter = "(&(objectClass=user)(sAMAccountName=" + UserName + "))";
                    DirectoryEntry usr = deSearcher.FindOne().GetDirectoryEntry();
                    
                    usr.Invoke("ChangePassword", new Object[2] { oldPass, newPwd });
                    //usr.Invoke("SetPassword", new object[] { newPwd });
                    //usr.Password = newPwd;
                    usr.CommitChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static string Chr(int asciiCode)
        {
            if (asciiCode >= 0 && asciiCode <= 255)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter);
            }
            else
            {
                throw new Exception("ASCII Code is not valid.");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            panelNewPassword.Visible = false;
            txtDomainName.Text = Environment.UserDomainName;
            txtCurUserName.Text = Environment.UserName;
            
        }

        private void chkChangePwd_CheckedChanged(object sender, EventArgs e)
        {
            if (chkChangePwd.Checked)
            {
                panelNewPassword.Visible = true;
            }
            else
            {
                panelNewPassword.Visible = false;
            }
        }

        private void chkResetCurrent_CheckedChanged(object sender, EventArgs e)
        {
            if (chkResetCurrent.Checked)
            {
                txtNewPwd.Text = "";
                txtNewPwd.ReadOnly = true;
            }
            else
            {
                txtNewPwd.ReadOnly = false;
            }
        }

    }
}